Skip to main content

Guide: Set Up a C# Client with TideCloak on IIS

This guide will help you set up TideCloak for managing user authentication in a C# client application using IIS. Follow the steps below to configure and customize the example provided.

Prerequisites

Before you begin, ensure that you have:

  • A TideCloak instance running locally or on a server.
  • A realm and a client configured in TideCloak.
  • Basic knowledge of C# and .NET.
  • .NET Core SDK installed on your machine.

0: Set Up Tidecloak and Tide IDP

Before starting the integration, make sure you have both Tidecloak and the TIDE Identity Provider (IDP) set up and running. This is crucial for managing user authentication in your application. You can refer to the following setup guides:

  • How to Set Up Tidecloak – In this guide, you will configure Tidecloak with the same values used in this tutorial (e.g., localhost:8000 for the Core app).
  • How to Set Up the TIDE IDP – This guide helps you configure the TIDE Identity Provider, which will serve as your authentication server.

By following these setup guides, you'll ensure your environment is ready to integrate with your app using the values provided in this tutorial. Please continue with the steps below to integrate Tide using IIS.

1. Set Up the Development Environment

1: Install IIS

Open Control Panel :

  • Go to Control Panel > Programs > Programs and Features > Turn Windows features on or off.

    Enable IIS :

  • In the "Windows Features" window, scroll down and find Internet Information Services (IIS) .

  • Check the box next to Internet Information Services .

  • Expand IIS and make sure Web Management Tools and World Wide Web Services are selected.

  • Click OK to install.

2. Install .NET Core SDK

First, you need to have the .NET Core SDK installed on your machine. This SDK is required to build and run .NET applications.

  • Download and Install : You can download the latest version of the .NET Core SDK from the official .NET website.
  • Verify Installation : After installation, verify it by running the following command in your terminal or command prompt:
dotnet --version

This should return the installed .NET version.

3. Install the ASP.NET Core Module for IIS

Ensure that ASP.NET Core Hosting Bundle is installed on your IIS server, as this will allow the application to run.

  • Download the ASP.NET Core Hosting Bundle from here.
  • Run the installer on the machine where IIS is installed.

4. Set Up a Development Environment

You'll need an Integrated Development Environment (IDE) to write and manage your code. Here are a couple of popular options:

  • Visual Studio Code : A lightweight, free editor with support for .NET through extensions.
  • Download : Visual Studio Code
  • Install C# Extension : After installing Visual Studio Code, open it, go to Extensions (Ctrl+Shift+X), and search for the "C#" extension by Microsoft. Install it.

5. Create a New ASP.NET Core Project

You need to create a project where you will implement the TideCloak integration.

  • Command Line : Open a terminal and run the following command to create a new ASP.NET Core web application:
dotnet new webapp -o MyKeycloakApp

This will create a basic ASP.NET Core web application in a directory named MyKeycloakApp.

  • Open Project : Open the project in your chosen IDE (Visual Studio Code or Visual Studio).

6. Configure the Application for IIS Hosting Using VS Code

1. Modify launchSettings.json

Ensure your project is configured for IIS by adding an IIS profile to launchSettings.json. The file should already exist if you created the project using the dotnet new command. If not, you can create it in the Properties folder.

Add the following to launchSettings.json:

{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5000",
"sslPort": 44300
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"MyTideCloakApp": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "http://localhost:8000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS": {
"commandName": "IIS",
"launchBrowser": true,
"applicationUrl": "http://localhost/YourAppName",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

7. Install NuGet Packages

You'll need to add specific NuGet packages to your project to work with TideCloak. These packages provide the necessary libraries for client operations and JWT authentication.

  • Open Terminal : Open the terminal in your IDE or command prompt in the project directory.
  • Run the following commands to add the necessary packages :
dotnet add package OpenIddict.Client
dotnet add package OpenIddict.Client.AspNetCore
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
dotnet add package Microsoft.IdentityModel.Protocols.OpenIdConnect

These commands install:

  • OpenIddict.Client : For OpenIddict client operations.
  • OpenIddict.Client.AspNetCore : Integration with ASP.NET Core.
  • Microsoft.AspNetCore.Authentication.JwtBearer : For handling JWT tokens in your application.
  • Microsoft.AspNetCore.Authentication.OpenIdConnect : Adds OpenID Connect authentication support to your ASP.NET Core application for seamless integration with identity providers.
  • Microsoft.IdentityModel.Protocols.OpenIdConnect : Provides protocol support for handling OpenID Connect operations, including token exchange and validation, in your application.

8. Set Up the Project

Open the Program.cs file and add the following code to configure the authentication middleware:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using System.Security.Claims;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;

var builder = WebApplication.CreateBuilder(args);



builder.Services.AddRazorPages();

builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Authority = "http://localhost:8080/realms/realm";
options.ClientId = "myclient";
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;

options.RequireHttpsMetadata = false; // Set this to false for development

options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");

options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "preferred_username");
options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
options.ClaimActions.MapJsonKey("sub", "sub");
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

Important Configuration Notes

  • Authority : Replace "https://your-openiddict-server.com" with the URL of your TideCloak Server.
  • ClientId: Replace this with the credentials provided by your TideCloak Server.
  • RequireHttpsMetadata : Set this to false during development if your server does not support HTTPS, but ensure this is true in production.

9: Create Login and Logout Pages

To handle user authentication, you need to create login and logout pages. These pages will redirect users to TideCloak for authentication and handle the return to your application.

  1. Create Login Page (Pages/Login.cshtml)
@page
@model YourNamespace.Pages.LoginModel
@{
ViewData["Title"] = "Login";
}

<h2>Login</h2>
<p>You are being redirected to the login page...</p>

@section Scripts {
<script>
window.location.href = "/Account/Login";
</script>
}
  1. Create Logout Page (Pages/Logout.cshtml)
@page
@model YourNamespace.Pages.LogoutModel
@{
ViewData["Title"] = "Logout";
}

<h2>Logout</h2>
<p>You are being logged out...</p>

@section Scripts {
<script>
window.location.href = "/Account/Logout";
</script>
}

10:Create Code-Behind for Login and Logout Pages

Next, you'll create the code-behind files for the login and logout pages. These files contain the logic for handling the login and logout processes.

  1. Login Page (Pages/Login.cshtml.cs)
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace YourNamespace.Pages
{
public class LoginModel : PageModel
{
public IActionResult OnGet()
{
return Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectDefaults.AuthenticationScheme);
}
}
}
  1. Logout Page (Pages/Logout.cshtml.cs)
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace YourNamespace.Pages
{
public class LogoutModel : PageModel
{
public IActionResult OnGet()
{
return SignOut(new AuthenticationProperties { RedirectUri = "/" },
CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme);
}
}
}

11: Display User Details Page

Once the user has logged in, you may want to display some of the user's details such as their username, email, or other claims that are available. In this step, you'll create a page to display this information.

  1. Create User Details Page (Pages/UserDetails.cshtml)
@page
@model UserDetailsModel
@{
ViewData["Title"] = "User Details";
}

<h2>User Details</h2>

@if (User.Identity.IsAuthenticated)
{
<p><strong>Name:</strong> @User.Identity.Name</p>
<p><strong>Email:</strong> @User.FindFirst("email")?.Value</p>
<p><strong>Subject (sub):</strong> @User.FindFirst("sub")?.Value</p>
}
else
{
<p>You are not logged in.</p>
}

<a asp-page="/Index">Back to Home</a>
  1. Create Code-Behind for User Details Page (Pages/UserDetails.cshtml.cs)
using Microsoft.AspNetCore.Mvc.RazorPages;

public class UserDetailsModel : PageModel
{
public void OnGet()
{
// Any additional logic can go here if needed
}
}

12:Modify Index Page

To provide users with login and logout options, you'll need to modify the Index.cshtml page to include these buttons.

  1. Index Page (Pages/Index.cshtml)
@page
@model IndexModel
@{
ViewData["Title"] = "Home Page";
}

<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Welcome to TideCloak ASP.NET Core OAuth 2.0/OpenID Connect client application.</p>

@if (User.Identity.IsAuthenticated)
{
<a asp-page="/UserDetails" class="btn btn-primary">View User Details</a>
<a class="btn btn-primary" asp-page="/Logout">Logout</a>
}
else
{
<a class="btn btn-primary" asp-page="/Login">Login</a>
}
</div>

This code checks if the user is authenticated and displays the appropriate buttons. Authenticated users will see a "View User Details" and "Logout" button, while unauthenticated users will see a "Login" button.

2.Index Page (Pages/Index.cshtml.cs)

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MyKeycloakApp.Pages;

public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;

public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}

public void OnGet()
{

}
}

13: Publish the Application

To build and run your application:

  • Build the Application : Ensure everything is correctly set up by building the project:
dotnet publish --configuration Release --output ./publish

This will create a publish folder in your project directory with all the necessary files for deployment.

  • Copy to IIS : Once the application is published, copy the contents of the publish folder to the physical folder where IIS will serve your app (e.g., C:\inetpub\wwwroot\YourApp).

14: Test the Authentication Flow

  • Login : Click the login button and authenticate using your OpenIddict server.
  • Logout : Once logged in, test the logout functionality by clicking the logout button.

15: Set Up IIS

  1. Add a New Website :
  • Open IIS Manager .
  • Right-click Sites -> Add Website .
  • Fill in the details:
    • Site name : e.g., MyTideCloakApp
    • Physical path : Choose the folder where you published your application (C:\inetpub\wwwroot\YourApp).
    • Port: Choose a port to run the application on (e.g., 8000 as used in this guide).
  1. Bind to a Port :
  • Go to Bindings and ensure the site is bound to a hostname and port.

16: Run and Test

Restart IIS (iisreset from the command line or restart from the IIS Manager).

Navigate to https://localhost:8000 (or the port your application is running on) to access your application. Use the login button to start the TideCloak authentication process.

17: Try It Out - Full Example Code

Now that you've followed the steps to set up your ASP.NET Core application with TideCloak, it's time to see the full example in action. Below is the complete code that you can use to run the entire setup.

Full Example Code

Program.cs

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using System.Security.Claims;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;

var builder = WebApplication.CreateBuilder(args);

// Set the application to run on port 8000
builder.WebHost.UseUrls("http://localhost:8000");

builder.Services.AddRazorPages();

builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Authority = "http://localhost:8080/realms/realm";
options.ClientId = "myclient";
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;

options.RequireHttpsMetadata = false; // Set this to false for development

options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");

options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "preferred_username");
options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
options.ClaimActions.MapJsonKey("sub", "sub");
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

Login.cshtml

@page
@model YourNamespace.Pages.LoginModel
@{
ViewData["Title"] = "Login";
}

<h2>Login</h2>
<p>You are being redirected to the login page...</p>

@section Scripts {
<script>
window.location.href = "/Account/Login";
</script>
}

Logout.cshtml

@page
@model YourNamespace.Pages.LogoutModel
@{
ViewData["Title"] = "Logout";
}

<h2>Logout</h2>
<p>You are being logged out...</p>

@section Scripts {
<script>
window.location.href = "/Account/Logout";
</script>
}

Login.cshtml.cs

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace YourNamespace.Pages
{
public class LoginModel : PageModel
{
public IActionResult OnGet()
{
return Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectDefaults.AuthenticationScheme);
}
}
}

Logout.cshtml.cs

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace YourNamespace.Pages
{
public class LogoutModel : PageModel
{
public IActionResult OnGet()
{
return SignOut(new AuthenticationProperties { RedirectUri = "/" },
CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme);
}
}
}

UserDetails.cshtml

@page
@model UserDetailsModel
@{
ViewData["Title"] = "User Details";
}

<h2>User Details</h2>

@if (User.Identity.IsAuthenticated)
{
<p><strong>Name:</strong> @User.Identity.Name</p>
<p><strong>Email:</strong> @User.FindFirst("email")?.Value</p>
<p><strong>Subject (sub):</strong> @User.FindFirst("sub")?.Value</p>
}
else
{
<p>You are not logged in.</p>
}

<a asp-page="/Index">Back to Home</a>

UserDetails.cshtml.cs

using Microsoft.AspNetCore.Mvc.RazorPages;

public class UserDetailsModel : PageModel
{
public void OnGet()
{
// Any additional logic can go here if needed
}
}

Index.cshtml

@page
@model IndexModel
@{
ViewData["Title"] = "Home Page";
}

<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Welcome to TideCloak ASP.NET Core OAuth 2.0/OpenID Connect client application.</p>

@if (User.Identity.IsAuthenticated)
{
<a asp-page="/UserDetails" class="btn btn-primary">View User Details</a>
<a class="btn btn-primary" asp-page="/Logout">Logout</a>
}
else
{
<a class="btn btn-primary" asp-page="/Login">Login</a>
}
</div>

Index.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MyKeycloakApp.Pages;

public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;

public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}

public void OnGet()
{

}
}

launchSettings.json

{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5000",
"sslPort": 44300
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"MyTideCloakApp": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "http://localhost:8000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS": {
"commandName": "IIS",
"launchBrowser": true,
"applicationUrl": "http://localhost/YourAppName",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

🎉 Congratulations on setting up TideCloak for your C# Client using IIS! 🎉

You've successfully empowered your application with robust Identity and Access Management by integrating TideCloak. With this configuration, you can seamlessly manage user authentication within your C# client environment, while leveraging the enhanced security and flexibility that TideCloak provides. You're now prepared to elevate your application's security and user management to the next level!